﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace BookDownload
{
    class GetData
    {
        /// <summary>
        /// 返回输入URL的host部分，包含协议
        /// </summary>
        /// <param name="sURL">完整的URL地址，例如http://www.lieshu.net/dir/example.htm</param>
        /// <returns>返回主机头部分。http://www.lieshu.net/</returns>
        public static string getHostName(string sURL)
        {

            return sURL.Substring(0, sURL.IndexOf("/", 8));

        }
        /// <summary>
        /// 返回输入的URL的host部分，不包含协议
        /// </summary>
        /// <param name="sURL">完整的URL地址</param>
        /// <returns>仅主机头部分，不包含协议www.lieshu.net</returns>
        public static string getOnlyHostName(string sURL)
        {
            string host = getHostName(sURL);
            //去掉协议部分
            host=host.Substring(host.LastIndexOf("/")+1);
            return host;
        }
        /// <summary>
        /// 从指定网址中获取网页内容。
        /// </summary>
        /// <param name="url">网址</param>
        /// <param name="charSet">指定的字符编码格式</param>
        /// <returns>网页源代码</returns>
        public static string getHtml(string url, string charSet)
        //url是要访问的地址，charSet是目标网页的编码，如果传入的是null或者""，那就自动分析网页的编码 
        {
            string strWebData = "";

            WebClient myWebClient = new WebClient();
            myWebClient.Credentials = CredentialCache.DefaultCredentials;
            //C# 基础连接已经关闭: 发送时发生错误.参考一下链接
            //https://blog.csdn.net/sun49842566/article/details/82802297
            ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
            //获得数据
            byte[] myDataBuffer = myWebClient.DownloadData(url);
            strWebData = Encoding.Default.GetString(myDataBuffer);

            if (charSet != null && charSet != "" && Encoding.GetEncoding(charSet) != Encoding.Default)
                strWebData = Encoding.GetEncoding(charSet).GetString(myDataBuffer);
            return strWebData;
        }
        /// <summary>
        /// 包含参数的获取,如果有中文字符，必须先编码为与目标网页一致
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="param">参数</param>
        /// <param name="charSet">字符串格式</param>
        /// <param name="method">Post或者Get</param>
        /// <returns>网页内容</returns>
        public static string getHtml(string url, string param, string charSet, string method)
        {
            //默认为POST方法,utf-8编码
            if (method == "")
                method = "POST";
            if (charSet == "")
                charSet = "uft-8";

            WebClient myWebClient = new WebClient();
            //构建参数的比特串
            byte[] postData = Encoding.ASCII.GetBytes(param);
            //设置头
            myWebClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
            myWebClient.Headers.Add("ContentLength", postData.Length.ToString());
            //提交
            byte[] myDataBuffer = myWebClient.UploadData(url, method, postData);
            //解码
            return Encoding.GetEncoding(charSet).GetString(myDataBuffer);

        }
        /// <summary>
        /// 清理HTML源代码，去掉一些乱七八糟的格式
        /// </summary>
        /// <param name="sHtml">HTML源代码字符串</param>
        /// <param name="sRegContentExcept">自定义的删除内容</param>
        /// <returns>清理后的字符串</returns>
        public static string clearHTML(string sHtml, string sRegContentExcept)
        {
          
            sHtml = Regex.Replace(sHtml, "<[ /]*CENTER[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[ /]*UL[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[ /]*LI[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[ /]*SPAN[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[ ]*HR[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<!--[^\\f]*?-->", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[ /]*TABLE[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[ /]*FONT[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[ /]*TR[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[ /]*TD[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[ /]*BR[^<>]*>", "<P>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[ /]*STRONG>", "<P>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "&[a-z0-9#]{3,4};", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[^<>]*DIV[^<>]*>", "<P>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[^<>]*SCRIPT[^<>]*>[^<>]*<[^<>]*/SCRIPT[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[^<>]*FIELDSET[^<>]*>[^\v]*<[^<>]*/FIELDSET[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[^<>]*IFRAM[^<>]*>[^<>]*<[^<>]*/IFRAM[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[^<>]*SCRIPT[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);//去掉还没有配对的script
            sHtml = Regex.Replace(sHtml, "<[^<>]*A[^<>]*>[^<>]*<[^<>]*/A[^<>]*>", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);//所有的<A></A>
            sHtml = Regex.Replace(sHtml, "<[ /]*A[^<>]*>", "<P>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            sHtml = Regex.Replace(sHtml, "<[ /]*P[^<>]*>", "<P>", RegexOptions.IgnoreCase | RegexOptions.Multiline);//不同的段落格式装换为一种
            sHtml = Regex.Replace(sHtml, "[\\f\\n\\t\\r\\v]*", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);//去掉所有空白符号
            sHtml = Regex.Replace(sHtml, "<P>[<P> ]*<P>", "<P>", RegexOptions.IgnoreCase | RegexOptions.Multiline);//多个连续的仅放一个  

            //需要去掉的额外内容
            if (sRegContentExcept != ""&&sRegContentExcept!=null)
            {
                //以|间隔开为多个字符串
                string[] sArray = sRegContentExcept.Split('|');
                for (int i = 0; i < sArray.Length; i++)
                    sHtml = sHtml.Replace(sArray[i],"");
            }

            return sHtml;
        }
        /// <summary>
        /// 获得网页标题部分
        /// </summary>
        /// <param name="sHtml">源文件</param>
        /// <param name="sRegTitle">处理得正则表达式</param>
        /// <returns>标题字符串</returns>
        public static string getTitle(string sHtml, string sRegTitle)
        {
            string sTitle = string.Empty;
            Match match = Regex.Match(sHtml, sRegTitle, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            if (match.Success)
            {
                sTitle = match.Groups[1].Value;
            }
            return sTitle;
        }
        /// <summary>
        /// 获得内容
        /// </summary>
        /// <param name="sHostName">主机名</param>
        /// <param name="sHtml">HTML源代码</param>
        /// <param name="sRegConent">处理的正则表达</param>
        /// <param name="sRegExcept">需要特别处理的字符串</param>
        /// <returns>处理后结果</returns>
        public static string getContent(string sHtml, string sRegContent, string sRegExcept)
        {
            string sContent = string.Empty;
            string sOldImageURL = string.Empty;
            Match match = Regex.Match(sHtml, sRegContent, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            if (match.Success)
                sContent = match.Groups[1].Value;
            else//如果没有成功，就以BODY再来一次
            {
                match = Regex.Match(sHtml, "<[^<>]*BODY[^<>]*>([^\\v]*)<[^<>]*/BODY>[^<>]*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                sContent = match.Groups[1].Value;//再不匹配就没办法了。
            }
            sContent = clearHTML(sContent, sRegExcept);
            return sContent;
        }
        /// <summary>
        /// 获得章节列表
        /// </summary>
        /// <param name="sHtml"></param>
        /// <param name="sRegList"></param>
        /// <returns></returns>
        public static ChapterList getList(string sHtml,string sRegList)
        {

            //获得所有的章节列表
            Match match = Regex.Match(sHtml, sRegList, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            int iOrder = 0; //计数
            string sURL = "";
            string sTitle = "";
            string sReplaceContent = "";
            //URL列表
            ChapterList biBook=new ChapterList();
            
            while (match.Success)
            {
                sURL = match.Groups[1].Value;
                sTitle = match.Groups[2].Value.Trim();
                sTitle = Regex.Replace(sTitle, "[\\s]*\\s", " ", RegexOptions.IgnoreCase | RegexOptions.Multiline);

                biBook.URL.Add(sURL);
                biBook.Title.Add(sTitle);

                sReplaceContent += "<div><a title=\"" + sURL + "\">" + sTitle + "</a></div>\r\n";

                match = match.NextMatch();
                iOrder++;
            }
            return biBook;
        }
        /// <summary>
        /// 返回真实地址
        /// </summary>
        /// <param name="book_index"></param>
        /// <param name="chapter_url"></param>
        /// <returns></returns>
        public static string getRealChapterURL(string book_index,string chapter_url){
            //如果章节的第一个符号是/，表示是从根目录开始的，那就用网站根去连接
            string result = "";
            if (chapter_url.Substring(0, 1) == "/")
            {
                result = getHostName(book_index) + chapter_url;
            }
            else
            {
                result = book_index + chapter_url;
            }
            return result;
        }
    }
}
